import * as THREE from '../../node_modules/three/build/three.module.js';
import { OrbitControls } from '../../node_modules/three/examples/jsm/controls/OrbitControls.js';
import Stats from '../../node_modules/three/examples/jsm/libs/stats.module.js';
import { Line2 } from '../../node_modules/three/examples/jsm/lines/Line2.js';
import { LineMaterial } from '../../node_modules/three/examples/jsm/lines/LineMaterial.js';
import { LineGeometry } from '../../node_modules/three/examples/jsm/lines/LineGeometry.js';
import { TWEEN } from '../../node_modules/three/examples/jsm/libs/tween.module.min.js';

import vertexShader from '../shader/vertexShader.glsl?raw';
import fragmentShader from '../shader/fragmentShader.glsl?raw';
import vertexShader2 from '../shader/vertexShader2.glsl?raw';
import fragmentShader2 from '../shader/fragmentShader2.glsl?raw';

export default function three3D(Dom, myChart) {
    let renderer, camera, scene, light, stats, controls, geometry, material, line, matLine, mesh, stars, uniforms;
    // const echartsCanvasArr = echartsCanvas;
    const radius = 5;
    const width = Dom.clientWidth, height = Dom.clientHeight;
    const group = new THREE.Group();
    const groupDots = new THREE.Group();
    const groupLines = new THREE.Group();
    const groupHalo = new THREE.Group(); //卫星环+小卫星
    const aGroup = new THREE.Group();

    var initFlag = false;
    var WaveMeshArr = [];//所有波动光圈集合
    var planGeometry = new THREE.BufferGeometry(1, 1); //默认在XOY平面上
    var globeTextureLoader = new THREE.TextureLoader();
    var map = new THREE.Object3D();
    var camaPositions = [
        { x: 5, y: - 20, z: 200 }, //远处
        { x: 0.5, y: - 2, z: 20 }//近处
    ];
    var API = {
        c: 1.7,
        p: 2.3,
        color: 0x10105
    };
    var uniforms2 = {
        u_time: { value: 0.0 }
    };
    const posArr = [
        { 'x': - 1.7049594735603837, 'y': 3.208354470512221, 'z': - 3.4350509144786985 },
        { 'x': - 2.1965610576118175, 'y': 2.1955955192304506, 'z': - 3.9184792759587768 },
        { 'x': - 2.2290975556080355, 'y': 2.6054406912933263, 'z': - 3.639066211507457 },
        { 'x': 0.5738958419746141, 'y': - 0.44114968930852216, 'z': 4.9473255920938985 },
        { 'x': - 0.9326350073394328, 'y': 2.8399222968004114, 'z': - 4.00812091773949 },
        { 'x': 3.469198597393574, 'y': 1.2295167303380952, 'z': - 3.3842206934036057 },
        { 'x': - 2.4019084876611916, 'y': - 2.190220428765315, 'z': 3.7991801866087123 },
        { 'x': - 2.49363689878109, 'y': - 4.099696049856375, 'z': 1.4050862307450966 },
        { 'x': - 2.3729307780326305, 'y': 2.840227787960863, 'z': 3.3618901878497454 },
        { 'x': - 2.0636200279017873, 'y': 0.7444294629976027, 'z': - 4.493027615657812 },
        { 'x': 0.47725894517680106, 'y': 2.4327372143508037, 'z': - 4.34212085796347 },
        { 'x': - 2.4777001955161246, 'y': - 1.2092952460724242, 'z': 4.171163716394502 },
        { 'x': - 0.03915748918627658, 'y': - 0.008362945319338826, 'z': 4.999839672648135 },
        { 'x': 1.5223738738260317, 'y': - 1.032865814102439, 'z': - 4.649254348640267 },
        { 'x': - 0.26640112020426315, 'y': - 4.314854187280748, 'z': 2.5121830716848077 },
        { 'x': - 4.031470206741836, 'y': - 2.606648761952297, 'z': - 1.3973654511134501 },
        { 'x': 0.8544382232162094, 'y': 1.5274953155132989, 'z': 4.683662390031124 },
        { 'x': 3.0409624989238546, 'y': 1.76433738825175, 'z': - 3.555230043268055 },
        { 'x': - 4.721251023266457, 'y': 1.2354922989397954, 'z': - 1.0878177947459262 },
        { 'x': 2.1518961827021106, 'y': 3.891904027152385, 'z': - 2.285262755638206 },
        { 'x': 0.8501960736517479, 'y': - 2.851729208821255, 'z': - 4.018060123480341 },
        { 'x': 2.5631840141785176, 'y': 4.263234820997851, 'z': - 0.5048926326370041 },
        { 'x': - 0.4580143454812531, 'y': - 2.6523265200067385, 'z': 4.213714144386437 }
    ];


    /**
     * @desc 3d球面取点
     * @param <number> radius ...
     * @param <number> a ...
     * @param <number> b ...
     * @return <object> x,y,z
     */
    function getPos(radius, a, b) {

        var x = radius * Math.sin(a) * Math.cos(b);
        var y = radius * Math.sin(a) * Math.sin(b);
        var z = radius * Math.cos(a);
        return { x, y, z };
    }

    //threejs自带的经纬度转换
    function lglt2xyz(lng, lat) {
        const theta = (90 + lng) * (Math.PI / 180);
        const phi = (90 - lat) * (Math.PI / 180);
        return (new THREE.Vector3()).setFromSpherical(new THREE.Spherical(radius, phi, theta));
    }

    /**
     * 经纬度坐标转球面坐标
     * @param {地球半径} R
     * @param {经度(角度值)} longitude
     * @param {维度(角度值)} latitude
     */
    function lon2xyz(R, longitude, latitude) {
        var lon = longitude * Math.PI / 180;//转弧度值
        var lat = latitude * Math.PI / 180;//转弧度值
        lon = - lon;// three.js坐标系z坐标轴对应经度-90度，而不是90度
        // 经纬度坐标转球面坐标计算公式
        var x = R * Math.cos(lat) * Math.cos(lon);
        var y = R * Math.sin(lat);
        var z = R * Math.cos(lat) * Math.sin(lon);
        // 返回球面坐标
        return {
            x: x,
            y: y,
            z: z,
        };
    }

    /**
     * @desc 随机设置点
     * @param <Group> group ...
     * @param <number> radius ...
     */
    function setRandomDot(group) {
        var texture = new THREE.TextureLoader().load('/src/assets/textures/标注.png');
        var texture2 = new THREE.TextureLoader().load('/src/assets/textures/标注光圈.png');
        posArr.map(pos => {
            var dotMesh = createPointMesh(pos, texture);
            var waveMesh = createWaveMesh(pos, texture2);
            group.add(dotMesh);
            group.add(waveMesh);
            WaveMeshArr.push(waveMesh);
        });
    }

    /**
     * 标注
     */
    function createPointMesh(pos, texture) {
        var material = new THREE.MeshBasicMaterial({
            map: texture,
            transparent: true, //使用背景透明的png贴图，注意开启透明计算
            // side: THREE.DoubleSide, //双面可见
            depthWrite: false, //禁止写入深度缓冲区数据
        });
        var mesh = new THREE.Mesh(planGeometry, material);
        var size = radius * 0.04;//矩形平面Mesh的尺寸
        mesh.scale.set(size, size, size);//设置mesh大小
        //设置mesh位置
        mesh.position.set(pos.x, pos.y, pos.z);
        // mesh在球面上的法线方向(球心和球面坐标构成的方向向量)
        var coordVec3 = new THREE.Vector3(pos.x, pos.y, pos.z).normalize();
        // mesh默认在XOY平面上，法线方向沿着z轴new THREE.Vector3(0, 0, 1)
        var meshNormal = new THREE.Vector3(0, 0, 1);
        // 四元数属性.quaternion表示mesh的角度状态
        //.setFromUnitVectors();计算两个向量之间构成的四元数值
        mesh.quaternion.setFromUnitVectors(meshNormal, coordVec3);
        return mesh;
    }

    /**
     * 标注的光圈
     */
    function createWaveMesh(pos, texture) {
        var material = new THREE.MeshBasicMaterial({
            color: 0x22ffcc,
            map: texture,
            transparent: true, //使用背景透明的png贴图，注意开启透明计算
            opacity: 1.0,
            // side: THREE.DoubleSide, //双面可见
            depthWrite: false, //禁止写入深度缓冲区数据
        });
        var mesh = new THREE.Mesh(planGeometry, material);
        // var coord = lon2xyz(R*1.001, lon, lat)
        var size = radius * 0.055;//矩形平面Mesh的尺寸
        mesh.size = size;//自顶一个属性，表示mesh静态大小
        mesh.scale.set(size, size, size);//设置mesh大小
        mesh._s = Math.random() * 1.0 + 1.0;//自定义属性._s表示mesh在原始大小基础上放大倍数  光圈在原来mesh.size基础上1~2倍之间变化
        mesh.position.set(pos.x, pos.y, pos.z);
        // mesh姿态设置
        // mesh在球面上的法线方向(球心和球面坐标构成的方向向量)
        var coordVec3 = new THREE.Vector3(pos.x, pos.y, pos.z).normalize();
        // mesh默认在XOY平面上，法线方向沿着z轴new THREE.Vector3(0, 0, 1)
        var meshNormal = new THREE.Vector3(0, 0, 1);
        // 四元数属性.quaternion表示mesh的角度状态
        //.setFromUnitVectors();计算两个向量之间构成的四元数值
        mesh.quaternion.setFromUnitVectors(meshNormal, coordVec3);
        return mesh;
    }
    // 添加飞线
    function addLines(v0, v3) {
        // 夹角
        var angle = (v0.angleTo(v3) * 1.8) / Math.PI / 0.1; // 0 ~ Math.PI
        var aLen = angle * 0.4, hLen = angle * angle * 12;
        var p0 = new THREE.Vector3(0, 0, 0);
        // 法线向量
        var rayLine = new THREE.Ray(p0, getVCenter(v0.clone(), v3.clone()));
        // 顶点坐标
        var vtop = rayLine.at(hLen / rayLine.at(1).distanceTo(p0));
        // 控制点坐标
        var v1 = getLenVcetor(v0.clone(), vtop, aLen);
        var v2 = getLenVcetor(v3.clone(), vtop, aLen);
        // 绘制三维三次贝赛尔曲线
        var curve = new THREE.CubicBezierCurve3(v0, v1, v2, v3);
        var geometry = new LineGeometry();
        var points = curve.getSpacedPoints(50);
        var positions = [];
        var colors = [];
        var color = new THREE.Color();
        /**
         * HSL中使用渐变
         * h — hue value between 0.0 and 1.0
         * s — 饱和度 between 0.0 and 1.0
         * l — 亮度 between 0.0 and 1.0
         */
        for (var j = 0; j < points.length; j++) {
            // color.setHSL( .31666+j*0.005,0.7, 0.7); //绿色
            color.setHSL(.81666 + j, 0.88, 0.715 + j * 0.0025); //粉色
            colors.push(color.r, color.g, color.b);
            positions.push(points[j].x, points[j].y, points[j].z);
        }
        geometry.setPositions(positions);
        geometry.setColors(colors);
        var matLine = new LineMaterial({
            linewidth: 0.0006,
            vertexColors: true,
            dashed: false
        });

        return {
            curve: curve,
            lineMesh: new Line2(geometry, matLine)
        };
    }

    // 计算v1,v2 的中点
    function getVCenter(v1, v2) {
        const v = v1.add(v2);
        return v.divideScalar(2);
    }

    // 计算V1，V2向量固定长度的点
    function getLenVcetor(v1, v2, len) {
        const v1v2Len = v1.distanceTo(v2);
        return v1.lerp(v2, len / v1v2Len);
    }

    /**
     * @description 初始化渲染场景
     */
    function initRenderer() {
        renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(width, height);
        Dom.appendChild(renderer.domElement);
    }

    /**
     * @description 初始化相机
     */
    function initCamera() {
        camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
        camera.position.set(5, - 20, 200);
        camera.lookAt(0, 3, 0);
        window.camera = camera;
    }

    /**
     * @description 初始化场景
     */
    function initScene() {
        scene = new THREE.Scene();
        scene.background = new THREE.Color(0x020924);
        scene.fog = new THREE.Fog(0x020924, 200, 1000);
        window.scene = scene;
    }

    //辅助工具
    function initAuxiliaryTool() {
        const helper = new THREE.AxesHelper(500);
        scene.add(helper);
        // 网格
        var grid = new THREE.GridHelper(2, 10, 0x000000, 0x000000);
        grid.material.opacity = 0.2;
        grid.material.transparent = true;
        scene.add(grid);
    }

    //性能插件
    function initStats() {
        stats = new Stats();
        document.body.appendChild(stats.dom);
    }

    /**
     * 初始化用户交互
     **/
    function initControls() {
        controls = new OrbitControls(camera, renderer.domElement);
        // 如果使用animate方法时，将此函数删除
        // controls.addEventListener( 'change', render );
        // 使动画循环使用时阻尼或自转 意思是否有惯性
        controls.enableDamping = true;
        //动态阻尼系数 就是鼠标拖拽旋转灵敏度
        //controls.dampingFactor = 0.25;
        //是否可以缩放
        controls.enableZoom = true;
        //是否自动旋转
        controls.autoRotate = false;
        controls.autoRotateSpeed = 2;
        //设置相机距离原点的最远距离
        // controls.minDistance = 2;
        //设置相机距离原点的最远距离
        // controls.maxDistance = 1000;
        //是否开启右键拖拽
        controls.enablePan = true;
    }

    function initTween() {
        var tweena = cameraCon(3000);
        tweena.start();
    }

    function updateUvTransform() {
        uniforms.c.value = API.c;
        uniforms.p.value = API.p;
        uniforms.glowColor.value = new THREE.Color(API.color);
        renders();
    }

    function cameraCon(time) {
        var tween1 = new TWEEN.Tween(camaPositions[0]).to(camaPositions[1], time).easing(TWEEN.Easing.Quadratic.InOut);
        var update = () => {
            camera.position.set(camaPositions[0].x, camaPositions[0].y, camaPositions[0].z);
        };
        tween1.onUpdate(update);
        tween1.onComplete(function () {
            initFlag = true;
            //初始化点和曲线
            initDotAndFly();
            //光柱效果和底部矩形
            initLightPillar();
        });
        return tween1;
    }

    // 经纬度转地球坐标
    function createPosition(lnglat) {
        const spherical = new THREE.Spherical();
        spherical.radius = radius;
        const lng = lnglat[0];
        const lat = lnglat[1];
        const theta = (lng + 90) * (Math.PI / 180);
        const phi = (90 - lat) * (Math.PI / 180);
        spherical.phi = phi; //方位角
        spherical.theta = theta; //倾斜角
        const position = new THREE.Vector3();
        position.setFromSpherical(spherical);
        return position;
    }

    /**
     * @description 初始化光
     */
    function initLight() {
        const ambientLight = new THREE.AmbientLight(0xcccccc, 1.1);
        scene.add(ambientLight);
        var directionalLight = new THREE.DirectionalLight(0xffffff, 0.2);
        directionalLight.position.set(1, 0.1, 0).normalize();
        var directionalLight2 = new THREE.DirectionalLight(0xff2ffff, 0.2);
        directionalLight2.position.set(1, 0.1, 0.1).normalize();
        scene.add(directionalLight);
        scene.add(directionalLight2);
        var hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 0.2);
        hemiLight.position.set(0, 1, 0);
        scene.add(hemiLight);
        var directionalLight = new THREE.DirectionalLight(0xffffff);
        directionalLight.position.set(1, 500, - 20);
        directionalLight.castShadow = true;
        directionalLight.shadow.camera.top = 18;
        directionalLight.shadow.camera.bottom = - 10;
        directionalLight.shadow.camera.left = - 52;
        directionalLight.shadow.camera.right = 12;
        scene.add(directionalLight);
    }

    /**
     * 初始化背景星空
     */
    function initPoints() {
        var texture = new THREE.TextureLoader().load('/src/assets/textures/gradient.png');
        const positions = [];
        const colors = [];
        const geometry = new THREE.BufferGeometry();
        for (var i = 0; i < 10000; i++) {
            var vertex = new THREE.Vector3();
            vertex.x = Math.random() * 2 - 1;
            vertex.y = Math.random() * 2 - 1;
            vertex.z = Math.random() * 2 - 1;
            positions.push(vertex.x, vertex.y, vertex.z);
            var color = new THREE.Color();
            color.setHSL(Math.random() * 0.2 + 0.5, 0.55, Math.random() * 0.25 + 0.55);
            colors.push(color.r, color.g, color.b);
        }
        geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
        geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
        var starsMaterial = new THREE.PointsMaterial({
            map: texture,
            size: 1,
            transparent: true,
            opacity: 1,
            vertexColors: true, //true：且该几何体的colors属性有值，则该粒子会舍弃第一个属性--color，而应用该几何体的colors属性的颜色
            blending: THREE.AdditiveBlending,
            sizeAttenuation: true
        });
        stars = new THREE.Points(geometry, starsMaterial);
        stars.scale.set(300, 300, 300);
        scene.add(stars);
    }

    /**
     * 包含2个，一个地球，一个辉光球体
     */
    function initEarth() {
        // 地球
        globeTextureLoader.load('/src/assets/textures/earth2.jpg', function (texture) {
            var globeGgeometry = new THREE.SphereGeometry(radius, 100, 100);
            var globeMaterial = new THREE.MeshStandardMaterial({ map: texture, side: THREE.DoubleSide });
            var globeMesh = new THREE.Mesh(globeGgeometry, globeMaterial);
            group.rotation.set(0.5, 2.9, 0.1);
            group.add(globeMesh);
            scene.add(group);
        });
    }

    /**
     * 包含2个，一个地球，一个辉光球体
     */
    function initEarth2() {
        uniforms = {
            u_time: { value: 0.0 },
            c: { type: 'f', value: 2.3 }, //2.1 								// 系数
            p: { type: 'f', value: 1.7 }, //1.7 								// 强度
            diffuse: { // 用于实现扫描效果的贴图
                type: 't',
                value: new THREE.TextureLoader().load('/src/assets/textures/earth2.jpg')
            },
            glowColor: { type: 'c', value: new THREE.Color(0x10105) }, /// 光罩的颜色
            viewVector: { // 相机位置
                type: 'v3', value: new THREE.Vector3(0, 0, 1)
            },
            blending: THREE.AdditiveBlending
        };
        uniforms['diffuse'].value.wrapS = uniforms['diffuse'].value.wrapT = THREE.RepeatWrapping;
        var material = new THREE.ShaderMaterial({
            uniforms: uniforms,
            vertexShader: vertexShader,
            fragmentShader: fragmentShader,
            side: THREE.DoubleSide,
            // depthWrite: false,
            // transparent: true,
        });
        var globeGgeometry = new THREE.SphereGeometry(radius, 100, 100);
        var globeMesh = new THREE.Mesh(globeGgeometry, material);
        group.rotation.set(0.5, 2.9, 0.1);
        group.add(globeMesh);
        scene.add(group);
    }

    /**
     * 创建地球光晕特效
     */
    function initEarthSprite() {
        var texture = globeTextureLoader.load('/src/assets/textures/earth_aperture.png');
        var spriteMaterial = new THREE.SpriteMaterial({
            map: texture,
            transparent: true,
            opacity: 0.5,
            depthWrite: false
        });
        var sprite = new THREE.Sprite(spriteMaterial);
        sprite.scale.set(radius * 3, radius * 3, 1);
        group.add(sprite);
    }

    /**
     * 添加卫星特效
     */
    function initSatellite() {
        // 光环
        globeTextureLoader.load('/src/assets/textures/halo.png', function (texture) {
            var geometry = new THREE.PlaneGeometry(14, 14);//矩形平面
            var material = new THREE.MeshLambertMaterial({
                map: texture, //给纹理属性map赋值
                transparent: true,
                side: THREE.DoubleSide, //两面可见
                depthWrite: false
            });//材质对象
            var mesh = new THREE.Mesh(geometry, material);//网格模型对象
            groupHalo.add(mesh);
        });
        // 小地球
        globeTextureLoader.load('/src/assets/textures/smallEarth.png', function (texture) {
            var p1 = new THREE.Vector3(- 7, 0, 0);//顶点1坐标
            var p2 = new THREE.Vector3(7, 0, 0);//顶点2坐标
            const points = [p1, p2];
            const geometry = new THREE.BufferGeometry().setFromPoints(points);
            var material = new THREE.PointsMaterial({
                map: texture, //给纹理属性map赋值
                transparent: true,
                side: THREE.DoubleSide, //两面可见
                size: 1, //点对象像素尺寸
                depthWrite: false
            });//材质对象
            var earthPoints = new THREE.Points(geometry, material);//点模型对象
            groupHalo.add(earthPoints);//点对象添加到场景中
        });
        groupHalo.rotation.set(1.9, 0.5, 1);
        scene.add(groupHalo);
    }

    /**
     * 光柱特效
     */
    function createLightPillar(pos) {
        var height = radius * 0.1;//光柱高度，和地球半径相关，这样调节地球半径，光柱尺寸跟着变化
        var geometry = new THREE.BufferGeometry(radius * 0.05, height); //默认在XOY平面上
        geometry.rotateX(Math.PI / 2);//光柱高度方向旋转到z轴上
        geometry.translate(0, 0, height / 2);//平移使光柱底部与XOY平面重合
        var textureLoader = new THREE.TextureLoader(); // TextureLoader创建一个纹理加载器对象
        var material = new THREE.MeshBasicMaterial({
            map: textureLoader.load('/src/assets/textures/diqiu2/光柱.png'),
            color: 0x44ffaa, //光柱颜色，光柱map贴图是白色，可以通过color调节颜色
            transparent: true, //使用背景透明的png贴图，注意开启透明计算
            side: THREE.DoubleSide, //双面可见
            depthWrite: false, //是否对深度缓冲区有任何的影响
        });
        var mesh = new THREE.Mesh(geometry, material);
        var group = new THREE.Group();
        // 两个光柱交叉叠加
        group.add(mesh, mesh.clone().rotateZ(Math.PI / 2));//几何体绕x轴旋转了，所以mesh旋转轴变为z
        group.position.set(pos.x, pos.y, pos.z);//设置mesh位置
        var coordVec3 = new THREE.Vector3(pos.x, pos.y, pos.z).normalize();
        var meshNormal = new THREE.Vector3(0, 0, 1);
        // 四元数属性.quaternion表示mesh的角度状态
        //.setFromUnitVectors();计算两个向量之间构成的四元数值
        group.quaternion.setFromUnitVectors(meshNormal, coordVec3);
        return group;
    }

    /**
     * 光柱底部的矩形平面特效
     */
    function createLightWaveMesh(pos, texture) {
        var geometry = new THREE.BufferGeometry(1, 1); //默认在XOY平面上
        var material = new THREE.MeshBasicMaterial({
            color: 0x22ffcc,
            map: texture,
            transparent: true, //使用背景透明的png贴图，注意开启透明计算
            // side: THREE.DoubleSide, //双面可见
            depthWrite: false, //禁止写入深度缓冲区数据
        });
        var mesh = new THREE.Mesh(geometry, material);
        var size = radius * 0.05;//矩形平面Mesh的尺寸
        mesh.scale.set(size, size, size);//设置mesh大小
        return mesh;
    }

    /**
     * 光柱效果
     */
    function initLightPillar() {
        var texture = new THREE.TextureLoader().load('/src/assets/textures/标注.png');
        var datas = [
            {
                lng: 86.39895905468748, lat: 45.15923349468924 //合肥
            },
            {
                lng: 106.54041, lat: 29.40268 //重庆
            }
        ];
        datas.forEach(function (obj) {
            var pos = lglt2xyz(obj.lng, obj.lat);
            var LightPillar = createLightPillar(pos);
            groupDots.add(LightPillar);
            var waveMesh = createLightWaveMesh(pos, texture);
            LightPillar.add(waveMesh);
        });
    }

    /**
     * @description 初始化点和曲线
     */
    function initDotAndFly() {
        // 创建标注点
        setRandomDot(groupDots);
        //随机点加载group上面
        group.add(groupDots);
        // 曲线
        var animateDots = [];
        console.info("第一个坐标是多少")
        console.info(groupDots.children[0].position)
        groupDots.children.forEach(elem => {
            if (groupDots.children[0].position.x == elem.position.x) {
                return true;
            }
            // var line = addLines(groupDots.children[0].position, elem.position);
            // groupLines.add(line.lineMesh);
            // animateDots.push(line.curve.getPoints(100)); //这个是里面球
        });
        group.add(groupLines);
        // 添加动画
        for (let i = 0; i < animateDots.length; i++) {
            const aGeo = new THREE.SphereGeometry(0.03, 0.03, 0.03);
            const aMater = new THREE.MeshPhongMaterial({ color: '#F8D764' });
            const aMesh = new THREE.Mesh(aGeo, aMater);
            aGroup.add(aMesh);
        }
        var vIndex = 0;
        function animateLine() {
            aGroup.children.forEach((elem, index) => {
                const v = animateDots[index][vIndex];
                elem.position.set(v.x, v.y, v.z);
            });
            vIndex++;
            if (vIndex > 100) {
                vIndex = 0;
            }
            setTimeout(animateLine, 20);
        }
        group.add(aGroup);
        animateLine();
    }

    /**
     * 中国描边高亮
     */
    function initGeoJson() {
        const loader = new THREE.FileLoader();
        loader.load('./models/json/geoJson/china.json', function (data) {
            const jsonData = JSON.parse(data);
            initMap(jsonData);
        });
        loader.load('./models/json/geoJson/china-outline.json', function (data) {
            const jsonData = JSON.parse(data);
            outLineMap(jsonData);
        });
    }

    function outLineMap(json) {
        json.features.forEach(elem => {
            // 新建一个省份容器：用来存放省份对应的模型和轮廓线
            const province = new THREE.Object3D();
            const coordinates = elem.geometry.coordinates;
            coordinates.forEach(multiPolygon => {
                multiPolygon.forEach(polygon => {
                    // 这里的坐标要做2次使用：1次用来构建模型，1次用来构建轮廓线
                    if (polygon.length > 200) {
                        var v3ps = [];
                        for (let i = 0; i < polygon.length; i++) {
                            var pos = lglt2xyz(polygon[i][0], polygon[i][1]);
                            v3ps.push(pos);
                        }
                        var curve = new THREE.CatmullRomCurve3(v3ps, false/*是否闭合*/);
                        var color = new THREE.Vector3(0.5999758518718452, 0.7798940272761521, 0.6181903838257632);
                        var flyLine = initFlyLine(curve, {
                            speed: 0.4,
                            // color: randomVec3Color(),
                            color: color,
                            number: 3, //同时跑动的流光数量
                            length: 0.2, //流光线条长度
                            size: 3 //粗细
                        }, 5000);
                        province.add(flyLine);
                    }
                });
            });
            map.add(province);
        });
        group.add(map);
    }

    function initMap(chinaJson) {
        // 遍历省份构建模型
        chinaJson.features.forEach(elem => {
            // 新建一个省份容器：用来存放省份对应的模型和轮廓线
            const province = new THREE.Object3D();
            const coordinates = elem.geometry.coordinates;
            coordinates.forEach(multiPolygon => {
                multiPolygon.forEach(polygon => {
                    const lineMaterial = new THREE.LineBasicMaterial({ color: 0XF19553 }); //0x3BFA9E
                    const positions = [];
                    const linGeometry = new THREE.BufferGeometry();
                    for (let i = 0; i < polygon.length; i++) {
                        var pos = lglt2xyz(polygon[i][0], polygon[i][1]);
                        positions.push(pos.x, pos.y, pos.z);
                    }
                    linGeometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3));
                    const line = new THREE.Line(linGeometry, lineMaterial);
                    province.add(line);
                });
            });
            map.add(province);

        });
        group.add(map);
    }

    /**
     * @param curve {THREE.Curve} 路径,
     * @param matSetting {Object} 材质配置项
     * @param pointsNumber {Number} 点的个数 越多越细致
     * */
    function initFlyLine(curve, matSetting, pointsNumber) {
        var points = curve.getPoints(pointsNumber);
        var geometry = new THREE.BufferGeometry().setFromPoints(points);
        const length = points.length;
        var percents = new Float32Array(length);
        for (let i = 0; i < points.length; i += 1) {
            percents[i] = (i / length);
        }
        geometry.addAttribute('percent', new THREE.BufferAttribute(percents, 1));
        const lineMaterial = initLineMaterial(matSetting);
        var flyLine = new THREE.Points(geometry, lineMaterial);
        return flyLine;
    }

    function initLineMaterial(setting) {
        const number = setting ? (Number(setting.number) || 1.0) : 1.0;
        const speed = setting ? (Number(setting.speed) || 1.0) : 1.0;
        const length = setting ? (Number(setting.length) || 0.5) : 0.5;
        const size = setting ? (Number(setting.size) || 3.0) : 3.0;
        const color = setting ? setting.color || new THREE.Vector3(0, 1, 1) : new THREE.Vector3(0, 1, 1);
        const singleUniforms = {
            u_time: uniforms2.u_time,
            number: { type: 'f', value: number },
            speed: { type: 'f', value: speed },
            length: { type: 'f', value: length },
            size: { type: 'f', value: size },
            color: { type: 'v3', value: color }
        };
        const lineMaterial = new THREE.ShaderMaterial({
            uniforms: singleUniforms,
            vertexShader: vertexShader2,
            fragmentShader: fragmentShader2,
            transparent: true,
            //blending:THREE.AdditiveBlending,
        });
        return lineMaterial;
    }

    // 
    function initEchart() {
        let _myChart = myChart;
        console.log(myChart,"0-0-0-")
        _myChart.on('finished', function () {
            var spriteMap = new THREE.TextureLoader().load(myChart.getDataUrl());
            var spriteMaterial = new THREE.SpriteMaterial({
                transparent: true,
                map: spriteMap,
                side: THREE.DoubleSide
            });
            var sprite = new THREE.Sprite(spriteMaterial);
            sprite.type = 'Temperature';
            sprite.scale.set(250, 250, 1)
            let y = option.Height + 200;
            sprite.position.set(option.Position.X, y, option.Position.Z);
            //store3D.addObject(sprite);
            scene.push(sprite);
        })
    }

    /**
     * 窗口变动
     **/
    function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renders();
        renderer.setSize(window.innerWidth, window.innerHeight);
    }

    /**
     * @description 渲染
     */
    function renders() {
        renderer.clear();
        renderer.render(scene, camera);
    }

    /**
     * 更新
     **/
    function animate() {
        window.requestAnimationFrame(() => {
            if (controls) controls.update();
            if (stats) stats.update();
            if (TWEEN) TWEEN.update();
            if (initFlag) {
                //光环
                groupHalo.rotation.z = groupHalo.rotation.z + 0.01;
                group.rotation.y = group.rotation.y + 0.001;
                // 所有波动光圈都有自己的透明度和大小状态
                // 一个波动光圈透明度变化过程是：0~1~0反复循环
                if (WaveMeshArr.length) {
                    WaveMeshArr.forEach(function (mesh) {
                        mesh._s += 0.007;
                        mesh.scale.set(mesh.size * mesh._s, mesh.size * mesh._s, mesh.size * mesh._s);
                        if (mesh._s <= 1.5) {
                            //mesh._s=1，透明度=0 mesh._s=1.5，透明度=1
                            mesh.material.opacity = (mesh._s - 1) * 2;
                        } else if (mesh._s > 1.5 && mesh._s <= 2) {
                            //mesh._s=1.5，透明度=1 mesh._s=2，透明度=0
                            mesh.material.opacity = 1 - (mesh._s - 1.5) * 2;
                        } else {
                            mesh._s = 1.0;
                        }
                    });
                }
            }
            if (stars) {
                stars.rotation.y += .0001;
            }
            uniforms2.u_time.value += 0.007;
            renders();
            animate();
        });
    }

    window.onload = () => {
        initRenderer();
        initCamera();
        initScene();
        initLight();
        // initAuxiliaryTool();
        // initStats();
        //初始化地球
        initEarth();
        // initEarth2(); //地球2使用菲尼尔反射效果，可以配合GUI使用，使用记得开启initGui()方法注释
        //卫星特效
        initSatellite();
        //地球光晕
        initEarthSprite();
        //初始化动态星空背景
        initPoints();
        //初始化点和曲线，放在tween动画完成后调用
        // initDotAndFly();

        //外圈中国描边高亮
        initGeoJson();
        initControls();
        initTween();
        initEchart()
        // initGui();
        animate();

        window.addEventListener('resize', onWindowResize, false);
    }
}